#include "Mid_I2CMasterDrv.h"

unsigned char u8EepromWriteDelayTim;

typedef struct
{
    unsigned char u8Chn;
    unsigned char fgNoAck[U8_HAL_I2C_NUM];
    void (*I2cMasterPortInit)(unsigned char u8Chn);
    void (*I2cMasterSclPortSet)(unsigned char u8Chn,unsigned char u8Tmp);
    void (*I2cMasterSdaPortSet)(unsigned char u8Chn,unsigned char u8Tmp);
    void (*I2cMasterSdaPortSetInput)(unsigned char u8Chn);
    void (*I2cMasterSdaPortSetOutput)(unsigned char u8Chn);
    unsigned char (*ReadI2cMasterSdaPinStatus)(unsigned char u8Chn);
    
} ST_HAL_I2CMASTER_DRV;

ST_HAL_I2CMASTER_DRV stHalI2cMasterDrv;


void HalMasterI2cStartBit(unsigned char u8Chn)
{
    stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_HIGH);
    CommonDelayUs(U8_DELAY_TIM);
    stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);
    CommonDelayUs(U8_DELAY_TIM);
    stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_LOW);
    CommonDelayUs(U8_DELAY_TIM);
    stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);
    CommonDelayUs(U8_DELAY_TIM);
}

void HalMasterI2cStopBit(unsigned char u8Chn)
{
	stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_LOW);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_HIGH);
	CommonDelayUs(U8_DELAY_TIM);
}

void HalI2cDevReset(unsigned char u8Chn)
{
    stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);
    CommonDelayUs(U8_DELAY_TIM);
    stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);
    CommonDelayUs(U8_DELAY_TIM);
    stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);
    CommonDelayUs(U8_DELAY_TIM);
    HalMasterI2cStopBit(u8Chn);
}

void HalMasterI2cAck(unsigned char u8Chn)
{
	stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_LOW);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);
	CommonDelayUs(U8_DELAY_TIM);

}

void HalI2cSlaveAck(unsigned char u8Chn)
{
    unsigned char u8ErrTime;
    u8ErrTime = 0;
    stHalI2cMasterDrv.I2cMasterSdaPortSetInput(u8Chn);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.fgNoAck[u8Chn] = 0;
	while (stHalI2cMasterDrv.ReadI2cMasterSdaPinStatus(u8Chn) != 0)
	{
        u8ErrTime++;
       
        if(u8ErrTime > 250)
		{
            stHalI2cMasterDrv.fgNoAck[u8Chn] = 1;     
            break;
        }
        
	}
	
    CommonDelayUs(U8_DELAY_TIM);
    //CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);
	CommonDelayUs(U8_DELAY_TIM);
	//stHalI2cMasterDrv.I2cMasterSdaPortSetOutput(u8Chn);	
	//CommonDelayUs(U8_DELAY_TIM);
} 

void HalMasterI2cNack(unsigned char u8Chn)
{
	stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_HIGH);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);
	CommonDelayUs(U8_DELAY_TIM);
	stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_LOW);
	CommonDelayUs(U8_DELAY_TIM);
}

void HalMasterI2cWrite8Bit(unsigned char u8Chn, unsigned char u8Data)
{
	unsigned char i;
									
	for (i = 0; i < 8; i++)
	{
        ///<高位优先
        #if U8_BIG_ENDIAN == 1
        if ((u8Data & 0x80) == 0x80)
        {
            stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_HIGH);
        }
        else
        {
            stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_LOW);
        }
        u8Data = u8Data << 1;

        #else
        ///< 否则，低位优先
        if ((u8Data & 0x01) == 0x01)
        {
            stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_HIGH);
        }
        else
        {
            stHalI2cMasterDrv.I2cMasterSdaPortSet(u8Chn, U8_PIN_LOW);
        }
        u8Data = u8Data >> 1;
        #endif

        CommonDelayUs(U8_DELAY_TIM); ///<预留足够的延时时间，防止电容过大导致时钟线的电平变化比数据线的快
		stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);						
		CommonDelayUs(U8_DELAY_TIM);
		stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);					
		CommonDelayUs(U8_DELAY_TIM);
	}
}

unsigned char HalGetMasterI2cSlaveAckRsl(unsigned char u8Chn)
{
    unsigned char u8Tmp;

    u8Tmp = 0;
    if(u8Chn < U8_HAL_I2C_NUM)
    {
        u8Tmp = stHalI2cMasterDrv.fgNoAck[u8Chn];
    }
    
    return (u8Tmp);
}

void HalClcMasterI2cSlaveAckFg(unsigned char u8Chn)
{
    if(u8Chn < U8_HAL_I2C_NUM)
    {
        stHalI2cMasterDrv.fgNoAck[u8Chn] = 0;
    }
    
}

void HalMasterI2cRead8Bit(unsigned char u8Chn, unsigned char *p)
{
	unsigned char i;
	stHalI2cMasterDrv.I2cMasterSdaPortSetInput(u8Chn);
    CommonDelayUs(U8_DELAY_TIM);
	for (i = 0; i < 8; i++)
	{
		*p=*p<<1;			
		stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_HIGH);	
		CommonDelayUs(U8_DELAY_TIM);
		if (stHalI2cMasterDrv.ReadI2cMasterSdaPinStatus(u8Chn) != 0)
		{
			*p=*p|0x01;		
		}
		stHalI2cMasterDrv.I2cMasterSclPortSet(u8Chn, U8_PIN_LOW);	
		CommonDelayUs(U8_DELAY_TIM);
	}
    stHalI2cMasterDrv.I2cMasterSdaPortSetOutput(u8Chn);
}


void HalMasterI2cSendMultiByte(unsigned char u8Chn, unsigned char u8Addr,unsigned char *pData,unsigned char u8Len)
{    
    HalI2cDevReset(u8Chn);
    HalMasterI2cStartBit(u8Chn);
    HalMasterI2cWrite8Bit(u8Chn, u8Addr);
    HalI2cSlaveAck(u8Chn);
    for ( ; u8Len != 0; u8Len--)
	{
		HalMasterI2cWrite8Bit(u8Chn, *pData);
        HalI2cSlaveAck(u8Chn);
		pData++;
	}
	HalMasterI2cStopBit(u8Chn);

}


void HalMasterI2cReadMultiByte(unsigned char u8Chn, unsigned char u8Addr, unsigned char *pData,unsigned char u8Len)
{    
    HalI2cDevReset(u8Chn);
    HalMasterI2cStartBit(u8Chn);
    HalMasterI2cWrite8Bit(u8Chn, u8Addr);
    HalI2cSlaveAck(u8Chn);
    for (; u8Len != 1; u8Len--)
	{
		HalMasterI2cRead8Bit(u8Chn, pData);
        HalMasterI2cAck(u8Chn);
		pData++;
	}
	HalMasterI2cRead8Bit(u8Chn, pData);
	HalMasterI2cNack(u8Chn);
	HalMasterI2cStopBit(u8Chn);
	
}


/************************************************************************************/

void I2cMasterSdaPortSet(unsigned char u8Chn, unsigned char u8Tmp)
{
    if(u8Chn == U8_HAL_I2C_CH0)
    {
        if(U8_PIN_HIGH == u8Tmp)
        {
            SET_I2C_CH0_SDA_HIGH();
        }
        else
        {
            CLR_I2C_CH0_SDA_LOW();
        }
        
    }
    else if(u8Chn == U8_HAL_I2C_CH1)
    {
        ;
    }
    else
    {
        ;
    }
    //如有多路IIC设备在此按需新增
}

void I2cMasterSclPortSet(unsigned char u8Chn,unsigned char u8Tmp)
{
    if(u8Chn == U8_HAL_I2C_CH0)
    {
        if(U8_PIN_HIGH == u8Tmp)
        {
            SET_I2C_CH0_SCL_HIGH();
        }
        else
        {
            CLR_I2C_CH0_SCL_LOW();
        }
    }
    else if(u8Chn == U8_HAL_I2C_CH1)
    {
        ;
    }
    else
    {
        ;
    }
}

void I2cMasterSdaPortSetInput(unsigned char u8Chn)
{
    if(u8Chn == U8_HAL_I2C_CH0)
    {
        SET_I2C_CH0_SDA_INPUT();
    }
    else if(u8Chn == U8_HAL_I2C_CH1)
    {
        ;
    }
    else
    {
        ;
    }
}


void I2cMasterSdaPortSetOutput(unsigned char u8Chn)
{
    if(u8Chn == U8_HAL_I2C_CH0)
    {
        SET_I2C_CH0_SDA_OUTPUT();
    }
    else if(u8Chn == U8_HAL_I2C_CH1)
    {
        ;
    }
    else
    {
        ;
    }

}

unsigned char ReadI2cMasterSdaPinStatus(unsigned char u8Chn)
{
    unsigned char u8Tmp;

    u8Tmp = 0;
    if(u8Chn == U8_HAL_I2C_CH0)
    {
        u8Tmp = GET_I2C_CH0_SDA();
    }
    else
    {
        ;
    }
    return (u8Tmp);
}


void I2cMasterPortInit(unsigned char u8Chn)
{
    if(u8Chn == U8_HAL_I2C_CH0)
    {
        SET_I2C_CH0_SCL_HIGH();///<SCL
        SET_I2C_CH0_SDA_HIGH();///<SDA
    }
    else if(u8Chn == U8_HAL_I2C_CH1)
    {
        ;
    }
    else
    {
        ;
    }
}

void HalMasterI2cDevInit(void)
{

    stHalI2cMasterDrv.I2cMasterPortInit = I2cMasterPortInit;
    stHalI2cMasterDrv.I2cMasterSclPortSet = I2cMasterSclPortSet;
    stHalI2cMasterDrv.I2cMasterSdaPortSet = I2cMasterSdaPortSet;
    stHalI2cMasterDrv.I2cMasterSdaPortSetInput = I2cMasterSdaPortSetInput;
    stHalI2cMasterDrv.I2cMasterSdaPortSetOutput = I2cMasterSdaPortSetOutput;
    stHalI2cMasterDrv.ReadI2cMasterSdaPinStatus = ReadI2cMasterSdaPinStatus;

    stHalI2cMasterDrv.I2cMasterPortInit(U8_HAL_I2C_CH0);

}




